﻿using SocketCore.Network;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace SocketCore.Encoder
{
    public class ManualMessageEncoder : IMessageEncoder
    {
        public byte[] Encode(Message msg, IoSession session)
        {
            using(MemoryStream ms = new MemoryStream())
            {
                SerializerHelper.WriteInt((int)msg.Type, ms);
                SerializerHelper.WriteBoolean(msg.IsInternal, ms);

                switch (msg.Type)
                {
                    case PackageTypeEnum.Ascii:
                        SerializerHelper.WriteString(msg.Data.ToString(), ms);
                        break;
                    case PackageTypeEnum.Bitmap:
                        {
                            byte[] arrData = SerializeBitmap((Bitmap) msg.Data, 50);
                            SerializerHelper.WriteBytes(arrData, ms);
                        }
                        break;
                    case PackageTypeEnum.MemoryStream:
                        {
                            byte[] arrData = ((MemoryStream) msg.Data).GetBuffer();
                            SerializerHelper.WriteBytes(arrData, ms);
                        }
                        break;
                    case PackageTypeEnum.Heartbeat:
                        {
                            SerializerHelper.WriteString(msg.Data.ToString(), ms);
                            break;
                        }
                    default:
                        {
                            byte[] arrData = (byte[]) msg.Data;
                            SerializerHelper.WriteBytes(arrData, ms);
                        }
                        break;
                }
                return ms.ToArray();
            }
        }

        #region private utilities

        private byte[] SerializeBitmap(Bitmap bitmap, long quality)
        {
            using (MemoryStream msBitmap = new MemoryStream())
            {
                System.Drawing.Imaging.ImageCodecInfo ici = GetEncoderInfo("image/jpeg");
                System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters(1);
                eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                bitmap.Save(msBitmap, ici, eps);
                return msBitmap.ToArray();
            }
        }

        private ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
        }

        #endregion
    }
}
